/*
 * Date：10/23/18 10:15 PM
 * Author: guomw
 *
 */

package org.elanfox.intellicommunity.biz.service.core.resident.impl;

import org.elanfox.intellicommunity.biz.dto.condition.UserCondition;
import org.elanfox.intellicommunity.biz.dto.redis.RedisUserDTO;
import org.elanfox.intellicommunity.biz.dto.resident.UserSaveDTO;
import org.elanfox.intellicommunity.biz.entity.equipment.CardPO;
import org.elanfox.intellicommunity.biz.entity.resident.UserPO;
import org.elanfox.intellicommunity.biz.entity.resident.UserPO_;
import org.elanfox.intellicommunity.biz.repository.resident.UserRepository;
import org.elanfox.intellicommunity.biz.service.core.equipment.CardService;
import org.elanfox.intellicommunity.biz.service.core.resident.UserService;
import org.elanfox.intellicommunity.common.constant.RedisConstant;
import org.elanfox.intellicommunity.common.ienum.UserEnums;
import org.elanfox.intellicommunity.common.ienum.base.CodeDescEnumHelper;
import org.elanfox.intellicommunity.data.base.base.AbstractSearchableCrudService;
import org.elanfox.intellicommunity.data.base.base.SpecificationAndSort;
import org.elanfox.intellicommunity.data.base.dto.BaseSaveDTO;
import org.elanfox.intellicommunity.data.base.dto.BaseSearchDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;

/**
 * 用户相关service
 *
 * @author loutianxi
 * @date 2019-12-05
 */
@Service
public class UserServiceImpl extends AbstractSearchableCrudService<UserPO, Integer> implements UserService {

    @Autowired
    private UserRepository repository;
    @Autowired
    private CardService cardService;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    protected UserServiceImpl(UserRepository repository) {
        super(repository);
    }

    @Override
    protected SpecificationAndSort<UserPO> specificationAndSort(BaseSearchDTO condition) {
        UserCondition userCondition = (UserCondition) condition;
        Specification<UserPO> specification = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (userCondition.getDelFlag() != null) {
                predicates.add(cb.equal(root.get(UserPO_.delFlag), userCondition.getDelFlag()));
            }
            return cb.and(predicates.toArray(new Predicate[predicates.size()]));
        };
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        return new SpecificationAndSort<>(specification, sort);
    }

    @Override
    public UserPO save(BaseSaveDTO saveDTO) {
        UserSaveDTO userSaveDTO = (UserSaveDTO) saveDTO;
        UserPO userPO = findById(((UserSaveDTO) saveDTO).getUserId());
        //根据卡号查询用户,用于验证卡是否被绑定
        CardPO cardPO = cardService.find(userSaveDTO.getCardNo());
        if (cardPO == null) {
            throw new IllegalStateException("请输入系统中已录入的卡号");
        }
        if (cardPO.isDeleteStatus()) {
            throw new IllegalStateException("该卡已被注销");
        }
        if (!cardPO.isEnable()) {
            throw new IllegalStateException("该卡已被冻结");
        }
        //新增
        if (userPO == null) {
            if (cardPO.getUser() != null) {
                throw new IllegalStateException("该卡已被绑定!");
            }
            userPO = new UserPO();
        }
        //编辑
        else {
            if (cardPO.getUser() != null && cardPO.getUser().getUserId() != userPO.getUserId()) {
                throw new IllegalStateException("该卡已被绑定!");
            }
        }
        userPO.setAge(userSaveDTO.getAge());
        userPO.setName(userSaveDTO.getName());
        userPO.setSex(userSaveDTO.getSex());
        userPO.setFeature(CodeDescEnumHelper.getEnumTypeByCode(UserEnums.Feature.class, userSaveDTO.getFeature()));
        userPO.setUserType(userSaveDTO.getType());
        userPO.setMobile(userSaveDTO.getMobile());
        cardPO.setUser(userPO);
        userPO.setRoomNumber(userSaveDTO.getRoomNumber());
        userPO.setSteward(userSaveDTO.isSteward());
        cardService.save(cardPO);
        userPO = repository.save(userPO);
        //保存到redis
        redisTemplate.opsForHash().put(RedisConstant.KEY_USER, "user_" + userPO.getUserId(), new RedisUserDTO(userPO));
        return userPO;
    }

    @Override
    public List<UserPO> findDelFlagIsTrue() {
        return repository.findByDelFlagIsTrueAndCardIsNotNull();
    }

    @Override
    public boolean delUser(Integer userId) {
        //第一步判断是否绑定了定位卡
        UserPO userPO = findById(userId);
        if (userPO.getCard() != null) {
            throw new IllegalStateException("请先解绑，才能删除该用户!");
        }
        userPO.setDelFlag(false);
        save(userPO);
        //从redis中删除
        redisTemplate.opsForHash().delete(RedisConstant.KEY_USER, "user_" + userId);
        return true;
    }
}
